from ctypes import windll, byref, sizeof
from ctypes.wintypes import HWND, DWORD, RECT

user32 = windll.user32
dwmapi = windll.dwmapi
GetWindowRect = user32.GetWindowRect
SetWindowPos = user32.SetWindowPos
GetDesktopWindow = user32.GetDesktopWindow
DwmGetWindowAttribute = dwmapi.DwmGetWindowAttribute


def get_rect_no_shadow(hwnd):
    rect_noshadow = RECT()
    D_24_S = 9  # DMWA_EXTENDED_FRAME_BOUNDS
    DwmGetWindowAttribute(
        HWND(hwnd), DWORD(D_24_S), byref(rect_noshadow), sizeof(rect_noshadow)
    )
    # print(
    #     (
    #         rect_noshadow.left,
    #         rect_noshadow.top,
    #         rect_noshadow.right,
    #         rect_noshadow.bottom,
    #     )
    # )
    return rect_noshadow


def get_rect_with_shadow(hwnd):
    rect_shadow = RECT()
    GetWindowRect(hwnd, byref(rect_shadow))
    # print((rect_shadow.left, rect_shadow.top, rect_shadow.right, rect_shadow.bottom))
    return rect_shadow


class ShadowShift:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __str__(self) -> str:
        return str((self.x, self.y))


def get_shadow_shift(hwnd):
    rect_noshadow = get_rect_no_shadow(hwnd)
    rect_shadow = get_rect_with_shadow(hwnd)

    ssx = rect_shadow.left - rect_noshadow.left
    ssy = rect_shadow.top - rect_noshadow.top
    shadowshift = ShadowShift(ssx, ssy)
    # print(shadowshift)
    return shadowshift


def get_desktop_rect():
    desktop_rect = RECT()
    GetWindowRect(GetDesktopWindow(), byref(desktop_rect))
    # print(
    #     (desktop_rect.left, desktop_rect.top, desktop_rect.right, desktop_rect.bottom)
    # )
    return desktop_rect


def move_window(hwnd, x: int, y: int):
    ss = get_shadow_shift(hwnd)

    SWP_NOSIZE = 1
    SWP_NOZORDER = 4
    SetWindowPos(hwnd, 0, x + ss.x, y + ss.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER)


def move_window_to_left_top(hwnd):
    move_window(hwnd, 0, 0)


def move_window_to_left_bottom(hwnd):
    desktop_rect = get_desktop_rect()
    rect_noshadow = get_rect_no_shadow(hwnd)

    height_noshadow = rect_noshadow.bottom - rect_noshadow.top
    move_window(hwnd, 0, desktop_rect.bottom - height_noshadow)


def move_window_to_right_top(hwnd):
    desktop_rect = get_desktop_rect()
    rect_noshadow = get_rect_no_shadow(hwnd)

    width_noshadow = rect_noshadow.right - rect_noshadow.left
    move_window(hwnd, desktop_rect.right - width_noshadow, 0)


def move_window_to_right_bottom(hwnd):
    desktop_rect = get_desktop_rect()
    rect_noshadow = get_rect_no_shadow(hwnd)

    width_noshadow = rect_noshadow.right - rect_noshadow.left
    height_noshadow = rect_noshadow.bottom - rect_noshadow.top
    move_window(
        hwnd, desktop_rect.right - width_noshadow, desktop_rect.bottom - height_noshadow
    )


# 让 Windows 系统为我们取消 GetWindowRect 和 DwmGetWindowAttribute 之间的 DPI 差异
windll.shcore.SetProcessDpiAwareness(1)
# move_window_to_left_top(132736)
# move_window_to_left_bottom(132736)
# move_window_to_right_top(132736)
move_window_to_right_bottom(132736)
